/*
题目: 设计循环双端队列
设计实现双端队列。
实现 MyCircularDeque 类:

    MyCircularDeque(int k) ：构造函数,双端队列最大为 k 。
    boolean insertFront()：将一个元素添加到双端队列头部。 如果操作成功返回 true ，否则返回 false 。
    boolean insertLast() ：将一个元素添加到双端队列尾部。如果操作成功返回 true ，否则返回 false 。
    boolean deleteFront() ：从双端队列头部删除一个元素。 如果操作成功返回 true ，否则返回 false 。
    boolean deleteLast() ：从双端队列尾部删除一个元素。如果操作成功返回 true ，否则返回 false 。
    int getFront() )：从双端队列头部获得一个元素。如果双端队列为空，返回 -1 。
    int getRear() ：获得双端队列的最后一个元素。 如果双端队列为空，返回 -1 。
    boolean isEmpty() ：若双端队列为空，则返回 true ，否则返回 false  。
    boolean isFull() ：若双端队列满了，则返回 true ，否则返回 false 。

https://leetcode.cn/problems/design-circular-deque
 */
class MyCircularDeque {
    int[] queue = null;
    int length = 0;
    int usedSize = 0;
    int front = 0;  //负责--front, 减减后往左边走
    int rear = 0;   //负责rear ++; 往右边走后加加

    public MyCircularDeque(int k) {
        queue = new int[k];
        length = k;
    }

    public boolean insertFront(int value) {
        if (isFull()) {
            return false;
        }
        if (front == 0) {
            front = length - 1;
        } else {
            --front;
        }
        queue[front] = value;
        usedSize ++;
        return true;
    }

    public boolean insertLast(int value) {
        if (isFull()) {
            return false;
        }
        if (rear == length) {
            rear = 0;
        }
        queue[rear++] = value;
        usedSize ++;
        return true;
    }

    public boolean deleteFront() {
        if (isEmpty()) {
            return false;
        }
        front ++;
        if (front == length) {
            front = 0;
        }
        usedSize--;
        return true;
    }

    public boolean deleteLast() {
        if (isEmpty()) {
            return false;
        }
        if (rear == 0) {
            rear = length - 1;
        } else {
            rear --;
        }
        usedSize --;
        return true;
    }

    public int getFront() {
        if (isEmpty()) {
            return -1;
        }
        return queue[front];
    }

    public int getRear() {
        if (isEmpty()) {
            return -1;
        }
        if (rear != 0) {
            return queue[rear - 1];
        }
        return queue[length - 1];
    }

    public boolean isEmpty() {
        return usedSize == 0;
    }

    public boolean isFull() {
        return usedSize == length;
    }
}
